package DesignPatterns.prototype;


import java.util.Optional;

/**
 * 浅拷贝：只拷贝栈中的信息为浅拷贝，基础数据类型存在栈中，所以肯定浅拷贝，引用类型的引用也是存储在占中java在进行对象赋值时只是复制了一个引用所以也是浅拷贝，所以java默认情况是浅拷贝的。
 * 深拷贝：深拷贝就是将原对象的所有属性都从新复制一份形成一个新的对象，注意对象的属性也不能和原对象共用，这样才能算是原型模式
 * 需要对属性进行从新创建的，这样才能保证原型模式的正确。实现一个对象的完全复制
 */
public class DogPrototype implements Cloneable{
    private Dog dog;

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public DogPrototype clone() {
        try {
            DogPrototype clone = (DogPrototype) super.clone();
            Optional.ofNullable(clone.getDog()).ifPresent(dog->{
                // dog若是有属性也是需要进行操作的，其实最好是原型模式依赖的来也需要实现原型模式，那么就不需要考虑属性的属性的问题了
                // 只需保证自身属性从新创建即可
                clone.setDog(dog.clone());
            });
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

    public static void main(String[] args) {
        DogPrototype dogPrototype = new DogPrototype();
        dogPrototype.setDog(new Dog());
        DogPrototype dogPrototypeClone = dogPrototype.clone();
        System.out.println(dogPrototype == dogPrototypeClone);
        System.out.println(dogPrototype.getDog() == dogPrototypeClone.getDog());
    }
}

